/**************************************************************************************************
**                                                                                               **
**  文件名称:  dal_output_drv.c                                                                  **
**  版权所有:  CopyRight @ Xiamen Yaxon NetWork CO.LTD. 2017                                     **
**  文件描述:  I/O输出驱动控制                                                                   **
**  ===========================================================================================  **
**  创建信息:  | 2017-7-27 | LEON | 创建本模块                                                   **
**  ===========================================================================================  **
**  修改信息:  单击此处添加....                                                                  **
**************************************************************************************************/
#include "dal_include.h"
#include "dal_output_drv.h"

/*************************************************************************************************/
/*                           输出管脚管理结构                                                    */
/*************************************************************************************************/
typedef struct {
    INT8U               level;                                                 /* 当前输出状态 */
    OUTPUT_IO_T const  *pregt;                                                 /* 注册信息体 */
} PCB_T;

/*************************************************************************************************/
/*                           静态变量定义                                                        */
/*************************************************************************************************/
static PCB_T    s_pcb[OUTPUT_PORT_MAX];

/**************************************************************************************************
**  函数名称:  Output_Initiate
**  功能描述:  通用GPIO输出初始化
**  输入参数:  port: 输出口编号，见OUTPUT_IO_E
**  输出参数:  无
**  返回参数:  无
**************************************************************************************************/
static void Output_Initiate(OUTPUT_PORT_E port)
{
    const OUTPUT_IO_T *pinfo;
    GPIO_InitTypeDef   GPIO_InitStructure;
    
    if (port >= DAL_OUTPUT_GetMaxNum()) {
        return;
    }
    
    pinfo = DAL_OUTPUT_GetRegInfo(port);
    
    GPIO_InitStructure.GPIO_Pin   = pinfo->pin;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType = pinfo->mode;
    GPIO_InitStructure.GPIO_PuPd  = pinfo->dirct;
    
    GPIO_Init((GPIO_TypeDef *)pinfo->gbase, &GPIO_InitStructure);
}

/**************************************************************************************************
**  函数名称:  Output_Pullup
**  功能描述:  控制GPIO输出状态
**  输入参数:  port: 输出口编号，见OUTPUT_IO_E; pullup: 是否要拉高
**  输出参数:  无
**  返回参数:  无
**************************************************************************************************/
static void Output_CtrlPin(OUTPUT_PORT_E port, BOOLEAN pullup)
{
    const OUTPUT_IO_T *pinfo;
    
    if (port >= DAL_OUTPUT_GetMaxNum()) {
        return;
    }
    
    pinfo = DAL_OUTPUT_GetRegInfo(port);

    if (pullup == TRUE) {
        GPIO_SetBits((GPIO_TypeDef *)pinfo->gbase, pinfo->pin);
    } else {
        GPIO_ResetBits((GPIO_TypeDef *)pinfo->gbase, pinfo->pin);
    }
}

/**************************************************************************************************
**  函数名称:  DAL_OUTPUT_Init
**  功能描述:  初始化端口驱动
**  输入参数:  无
**  输出参数:  无
**  返回参数:  无
**************************************************************************************************/
void DAL_OUTPUT_Init(void)
{
    OUTPUT_PORT_E      i;
    OUTPUT_IO_T const *pregt;
    
    YX_MEMSET(&s_pcb, 0, sizeof(s_pcb));
    
    for (i = (OUTPUT_PORT_E)0; i < DAL_OUTPUT_GetMaxNum(); i++) {
        
        pregt = DAL_OUTPUT_GetRegInfo(i);                                      /* 获取注册信息 */
        
        s_pcb[i].pregt = pregt;
        s_pcb[i].level = pregt->level;
        
        Output_Initiate(i);
        
        if (pregt->level != 0) {                                               /* 拉高管脚输出 */
            Output_CtrlPin(i, TRUE);
        } else {                                                               /* 拉低管脚输出 */
            Output_CtrlPin(i, FALSE);
        }
    }

    DAL_ConfigWatchdog(TRUE);                                                  /* 首先启用看门狗功能 */
}

/**************************************************************************************************
**  函数名称:  DAL_OUTPUT_GetStatus
**  功能描述:  读取指定端口的当前状态
**  输入参数:  port: 输入口, 见OUTPUT_IO_E
**  输出参数:  无
**  返回参数:  1: 高电平状态; 0: 低电平状态
**************************************************************************************************/
INT8U DAL_OUTPUT_GetStatus(OUTPUT_PORT_E port)
{
    SYS_ASSERT((port < DAL_OUTPUT_GetMaxNum()), RETURN_FALSE);
    
    return s_pcb[port].level;
}

/**************************************************************************************************
**  函数名称:  DAL_OUTPUT_Pullup
**  功能描述:  拉高指定端口的输出
**  输入参数:  port: 输入口, 见OUTPUT_IO_E
**  输出参数:  无
**  返回参数:  无
**************************************************************************************************/
void DAL_OUTPUT_Pullup(OUTPUT_PORT_E port)
{
    SYS_ASSERT((port < DAL_OUTPUT_GetMaxNum()), RETURN_VOID);
    
    Output_CtrlPin(port, TRUE);
    s_pcb[port].level = 1;
}

/**************************************************************************************************
**  函数名称:  DAL_OUTPUT_Pulldown
**  功能描述:  拉低指定端口的输出
**  输入参数:  port: 输入口, 见OUTPUT_IO_E
**  输出参数:  无
**  返回参数:  无
**************************************************************************************************/
void DAL_OUTPUT_Pulldown(OUTPUT_PORT_E port)
{
    SYS_ASSERT((port < DAL_OUTPUT_GetMaxNum()), RETURN_VOID);
    
    Output_CtrlPin(port, FALSE);
    s_pcb[port].level = 0;
}

/**************************************************************************************************
**  函数名称:  DAL_ConfigWatchdog
**  功能描述:  看门狗配置
**  输入参数:  无
**  输出参数:  无
**  返回参数:  无
**************************************************************************************************/
void DAL_ConfigWatchdog(BOOLEAN enable)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_14;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd  = (enable == TRUE) ? GPIO_PuPd_UP : GPIO_PuPd_NOPULL;
    
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}

/**************************************************************************************************
**  函数名称:  DAL_ClearWatchdog
**  功能描述:  看门狗喂狗的动作
**  输入参数:  无
**  输出参数:  无
**  返回参数:  无
**************************************************************************************************/
void DAL_ClearWatchdog(void)
{
    if (DAL_OUTPUT_GetStatus(OUT_WATCHDOG) == 1) {
        DAL_OUTPUT_Pulldown(OUT_WATCHDOG);
    } else {
        DAL_OUTPUT_Pullup(OUT_WATCHDOG);
    }
}


